home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
168_01
/
com.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
10KB
|
415 lines
/* SDB - expression compiler
syntax:
<expr> ::= <lor> <EOS>
<lor> ::= <land> { '|' <land> }
<land> ::= <relat> { '&' <relat> }
<relat> ::= <primary> { <relop> <primary> }
<primary> ::= <factor> | <unop> <unary>
<factor> ::= <number> | <string> | '(' <query> ')'
<number> ::= <digit> | <number> <digit>
<string> ::= '"' <chars> '"'
<chars> ::= nil | <chars> <character>
<relop> ::= '=' | '<>' | '<' | '>' | '<=' | '>='
<unop> ::= '+' | '-' | '~'
*/
#include "sdbio.h"
extern int dbv_token;
extern char dbv_tstring[];
extern int dbv_tvalue;
extern int db_xand();
extern int db_xor();
extern int db_xnot();
extern int db_xlss();
extern int db_xleq();
extern int db_xeql();
extern int db_xgeq();
extern int db_xgtr();
extern int db_xneq();
extern int db_xpush();
extern int db_xstop();
static union codecell code[CODEMAX+1];
static int cndx;
static struct sel *selptr;
/* compile - compile a boolean expression */
int db_compile(slptr)
struct sel *slptr;
{
int result,i;
union codecell *cptr;
#ifdef Lattice
int (*dns)(); /*dns*/
#endif
/* save the selection structure pointer */
selptr = slptr;
/* initialize the code array index */
cndx = 0;
/* parse the boolean expression */
if (!expr(&result)) {
code[cndx++].c_operator = db_xstop;
freelit(code);
return (FALSE);
}
/* terminate the code */
code[cndx++].c_operator = db_xstop;
/* allocate space for the code array */
if ((cptr = malloc(sizeof(union codecell) * cndx)) == NULL) {
freelit(code);
return (FALSE);
}
/* store the code into the code array */
slptr->sl_where = cptr;
for (i = 0; i < cndx; i++) {
(*cptr++).c_operator = code[i].c_operator;
#ifndef Lattice
if (code[i].c_operator == db_xpush)
#else
if ( code[i].c_operator == (dns=db_xpush) ) /*dns*/
#endif
(*cptr++).c_operand = code[++i].c_operand;
}
/* return successfully */
return (TRUE);
}
/* db_fcode - free a code array */
db_fcode(slptr)
struct sel *slptr;
{
/* make sure there is a where clause */
if (slptr->sl_where == NULL)
return;
/* free the literals */
freelit(slptr->sl_where);
/* free the code array */
free(slptr->sl_where);
}
/* operator - insert an operator into the code array */
static int operator(opr)
int (*opr)();
{
/* insert the operator */
if (cndx < CODEMAX)
code[cndx++].c_operator = opr;
else
return (db_ferror(CDSIZE));
/* return successfully */
return (TRUE);
}
/* operand - insert an operand into the code array */
static int operand(opr)
struct operand *opr;
{
/* insert the push operator */
if (!operator(db_xpush))
return (FALSE);
/* insert the operand */
if (cndx < CODEMAX)
code[cndx++].c_operand = opr;
else
return (db_ferror(CDSIZE));
/* return successfully */
return (TRUE);
}
/* expr - compile an expression */
static int expr(result)
int *result;
{
int lval,rval;
if (!land(&lval))
return (FALSE);
while (db_token() == '|') {
db_ntoken();
if (!land(&rval))
return (FALSE);
if (!operator(db_xor))
return (FALSE);
}
*result = lval;
return (TRUE);
}
static int land(result)
int *result;
{
int lval,rval;
if (!relat(&lval))
return (FALSE);
while (db_token() == '&') {
db_ntoken();
if (!relat(&rval))
return (FALSE);
if (!operator(db_xand))
return (FALSE);
}
*result = lval;
return (TRUE);
}
static int relat(result)
int *result;
{
int lval,rval;
int tkn;
if (!primary(&lval))
return (FALSE);
while (db_token() <= LSS && dbv_token >= GTR) {
tkn = db_ntoken();
if (!primary(&rval))
return (FALSE);
switch (tkn) {
case LSS:
if (!operator(db_xlss))
return (FALSE);
break;
case LEQ:
if (!operator(db_xleq))
return (FALSE);
break;
case EQL:
if (!operator(db_xeql))
return (FALSE);
break;
case NEQ:
if (!operator(db_xneq))
return (FALSE);
break;
case GEQ:
if (!operator(db_xgeq))
return (FALSE);
break;
case GTR:
if (!operator(db_xgtr))
return (FALSE);
break;
}
}
*result = lval;
return (TRUE);
}
static int primary(result)
int *result;
{
int val;
int tkn;
if (db_token() == '~') {
tkn = db_ntoken();
if (!primary(&val))
return (FALSE);
switch (tkn) {
case '~':
if (!operator(db_xnot))
return (FALSE);
break;
}
}
else
if (!factor(&val))
return (FALSE);
*result = val;
return (TRUE);
}
static int factor(result)
int *result;
{
int val;
if (db_token() == '(') {
db_ntoken();
if (!expr(&val))
return (FALSE);
if (db_token() != ')')
return (db_ferror(SYNTAX));
db_ntoken();
}
else
if (!get_operand(&val))
return (FALSE);
*result = val;
return (TRUE);
}
/* get_operand - get an operand (number, string, or attribute) */
static int get_operand(result)
int *result;
{
/* determine operand type */
if (db_ntoken() == NUMBER)
return (get_number(result));
else if (dbv_token == ID)
return (get_attr(result));
else if (dbv_token == STRING)
return (get_string(result));
else
return (db_ferror(SYNTAX));
}
/* get_attr - get an attribute argument */
static int get_attr(result)
int *result;
{
struct operand *opr;
char rname[RNSIZE+1],aname[ANSIZE+1];
char *aptr; int atype,alen;
/* save the attribute name */
strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
/* check for a "." indicating a qualified attribute name */
if (db_token() == '.') {
db_ntoken();
/* the previous ID was really a relation name */
strcpy(rname,aname);
/* check for the real attribute name */
if (db_ntoken() != ID)
return (db_ferror(SYNTAX));
/* save the attribute name */
strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
/* lookup the attribute name */
if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen))
return (FALSE);
}
else
if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen))
return (FALSE);
/* get a new operand structure */
if ((opr = malloc(sizeof(struct operand))) == NULL)
return (db_ferror(INSMEM));
/* initialize the new operand structure */
opr->o_type = ATTR;
opr->o_value.ov_char.ovc_type = atype;
opr->o_value.ov_char.ovc_string = aptr;
opr->o_value.ov_char.ovc_length = alen;
/* insert the operand into the code array */
if (!operand(opr)) {
free(opr);
return (FALSE);
}
/* store operand type */
*result = atype;
/* return successfully */
return (TRUE);
}
/* get_number - get a numeric operand */
static int get_number(result)
int *result;
{
struct operand *opr;
/* get a new operand structure */
if ((opr = malloc(sizeof(struct operand))) == NULL)
return (db_ferror(INSMEM));
/* initialize the new operand structure */
o